#!/usr/bin/env python
# encoding: utf-8


"""
@file: qiuzuizhi.py
@time: 2017/4/26 上午11:52
"""
# 求最值得

from mathsolver.functions.base import *
from mathsolver.functions.budengshi import common_opers as co
from mathsolver.functions.budengshi.ineq_constants import INEQ_SEARCH_KEY, EQS_SEARCH_KEY
from mathsolver.functions.mathematica.mathematicaSolve import MathematicaOptimize
from itertools import chain


def get_known_eqs_and_ineqs(known):
    """
    提取Known中的等式和不等式
    :param known: 
    :return: 
    """
    _eqs = known.get(EQS_SEARCH_KEY, [])
    _eqs = _eqs if _eqs else []
    _ineqs = known.get(INEQ_SEARCH_KEY, [])
    _ineqs = _ineqs if _ineqs else []
    return _eqs, _ineqs


# 使用Mathematic求最值
# style1 Input paramer1: 要求的表达式; paramer2: 文本(最大值/最小值)
class FindOptimizeValue(BaseFunction):
    def solver(self, *args):
        self.label.add('均值不等式')
        arg1 = args[0]
        arg2 = args[1]
        if isinstance(arg1, BasePoly):
            f_expr = arg1.sympify()
        elif isinstance(arg1, BaseEq):
            _, f_expr = arg1.sympify()
        else:
            raise Exception('Illegal parameter')
        text = arg2
        op_type = 'Maximize' if text.find('最大值') >= 0 else 'Minimize'
        op_text = '最大值' if text.find('最大值') >= 0 else '最小值'
        eqs, ineqs = get_known_eqs_and_ineqs(self.known)
        symbs1 = co.eqs_symbs(eqs)
        symbs2 = sorted(set(co.ineqs_symbs(ineqs)))
        symbs = set(chain(symbs1, symbs2))
        if eqs and not ineqs:  # 如果只包含等式,不包含不等式
            op_value = MathematicaOptimize().solver(
                BaseOptimize(f_expr, op_type, BaseEqs(eqs)), BaseVariables(symbs)).output[
                0].value
        elif ineqs:
            _ineqs2 = list(chain(ineqs, eqs))
            op_value = MathematicaOptimize().solver(
                BaseOptimize(f_expr, op_type, BaseIneqs(_ineqs2)), BaseVariables(symbs)).output[
                0].value
        else:
            op_value = MathematicaOptimize().solver(
                BaseOptimize(f_expr, op_type), BaseVariables(symbs)).output[
                0].value
        self.steps.append(['求得' + new_latex(f_expr) + op_text, '为:' + new_latex(op_value)])
        self.output.append(BasePoly(op_value))
        return self


if __name__ == '__main__':
    pass
    # print '-------------QiuZuiZhi--------------------'
    # print FindOptimizeValue(known={'equations': [['a+b', '1'], ['m*n', '2']],
    #                                'inequations': [['a', '>', '0'], ['b', '>', '0'], ['m', '>', '0'],
    #                                                ['n', '>', '0']]}).solver(
    #     BasePoly('(a*m + b*n)*(b*m + a*n)'), '最大值').output[0].sympify()
    # print MathematicaOptimize().solver(
    #     BaseOptimize('(a*m + b*n)*(b*m + a*n)', 'Maximize', BaseIneqs(
    #         [['a', '>', '0'], ['b', '>', '0'], ['m', '>', '0'], ['n', '>', '0'], ['a + b', '1'], ['m*n', '2']])),
    #     BaseVariables(['a', 'b', 'm', 'n'])).output[
    #     0].value
    # print MathematicaOptimize().solver(
    #     BaseOptimize('x*y', 'Maximize', BaseIneqs(
    #         [['2*x + y', '<=', '10'], ['x + 2*y', '<=', '14'], ['x + y', '>=', '6']])),
    #     BaseVariables(['x', 'y'])).output[
    #     0].value
    # print FindOptimizeValue(known={'equations': [['1/a + 2/b', 'sqrt(a*b)']]}).solver(BasePoly('a*b'), '最小值').output[
    #     0].sympify()

    # print FindOptimizeValue(known={'inequations': [['pi', '<', 'x'], ['x', '<', '2*pi/3']]}).solver(
    #     BasePoly('sqrt(3)*sin(2*x) - cos(2*x)'), '最小值').output[
    #     0].sympify()

    # print FindOptimizeValue(known={'inequations': [['x + y', '>=', '1'], ['x**2 + y**2', '<=', '1']]}).solver(
    #     BasePoly('2*x + y'), '最小值').output[
    #     0].sympify()
    # print FindOptimizeValue(known={'inequations': [['x + y', '>=', '1'], ['x**2 + y**2', '<=', '1']]}).solver(
    #     BasePoly('2*x + y'), '最大值').output[
    #     0].sympify()
